<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Lifecycle</title>
    <style>
      html,
      body {
        margin: 0;
        height: 100%;
      }
      #container {
        display: flex;
        height: 100%;
      }
      #left {
        background-color: #f498b2;
        width: 50%;
        padding: 20px;
      }
      #right {
        background-color: #fce6ec;
        width: 50%;
        padding: 20px;
      }
      iframe {
        width: 100%;
        border: 1px solid #000;
      }
      button {
        outline: none;
        border: 1px solid #000;
        padding: 10px;
        cursor: pointer;
        background-color: #9b6da9;
      }
    </style>
  </head>
  <body>
    <div id="container">
      <div id="left">
        <iframe id="iframe" src="http://192.168.3.21:8000/Iframe.html"></iframe>
        <div>
          <button id="addBtn">添加组件</button>
          <button id="modifyBtn">修改第一个组件</button>
          <button id="removeBtn">移除第一个组件</button>
          <button id="moveBtn">移动第一个组件</button>
        </div>
        <hello-lifecycle count="1"></hello-lifecycle>
      </div>
      <div id="right">
        <h1>生命周期回调</h1>
        <ol id="consolePanel"></ol>
      </div>
    </div>
    <template id="helloLifecycle">
      <h1>Hello Lifecycle</h1>
      <div>显示一个随机数: <span id="count">0</span></div>
      <button id="btn">show count</button>
      <hr />
    </template>
    <script>
      const leftPanel = document.getElementById("left");
      const consolePanel = document.getElementById("consolePanel");

      function log(message) {
        const li = document.createElement("li");
        li.innerHTML = message;
        consolePanel.appendChild(li);
      }

      class HelloLifecycle extends HTMLElement {
        constructor() {
          super();
          const shadow = this.attachShadow({ mode: "open" });

          const templateDOM = document.getElementById("helloLifecycle");
          const cloneTemplate = templateDOM.content.cloneNode(true);

          const style = document.createElement('style');
            style.innerHTML = `
                hr {
                    border-color: #9b6da9;
                }

                button {
                    margin: 10px 0px;
                    outline: none;
                    border: 1px solid #242940;
                    padding: 10px;
                    cursor: pointer;
                    background-color: #242940;
                    color: #FFF;
                }
            `

            shadow.appendChild(style);
            shadow.appendChild(cloneTemplate);

            log("HelloLifecycle 被构造(constructor)");
        }
        connectedCallback() {
          log("HelloLifecycle 被添加到DOM tree(connectedCallback)");

          const btn = this.shadowRoot.querySelector("#btn");
          btn.addEventListener("click", this.showCount.bind(this));
        }

        static get observedAttributes() {
          return ["count"];
        }

        attributeChangedCallback(name, oldVal, newVal) {
          if (name === "count") {
            log(name + " 被更新 " + newVal + "(attributeChangedCallback)");
            const count = this.shadowRoot.getElementById("count");
            count.innerHTML = newVal;
          }
        }

        disconnectedCallback() {
          log("HelloLifecycle 从DOM tree上移除(disconnectedCallback)");

          const btn = this.shadowRoot.querySelector("#btn");
          btn.removeEventListener("click", this.showCount.bind(this));
        }

        adoptedCallback() {
          log("HelloLifecycle 从DOM tree上被移动(adoptedCallback)");
        }

        showCount() {
            const count = this.shadowRoot.getElementById("count");
            log(`current count is ${count.innerHTML}`);
        }
      }
      customElements.define("hello-lifecycle", HelloLifecycle);

      const addBtn = document.getElementById("addBtn");
      addBtn.addEventListener("click", () => {
        const helloLifecycle = document.createElement("hello-lifecycle");
        leftPanel.appendChild(helloLifecycle);
      });

      const modifyBtn = document.getElementById("modifyBtn");
      modifyBtn.addEventListener("click", () => {
        const helloLifecycle = document.querySelector("hello-lifecycle");
        if (helloLifecycle)
          helloLifecycle.setAttribute("count", Math.ceil(Math.random() * 10));
      });

      const removeBtn = document.getElementById("removeBtn");
      removeBtn.addEventListener("click", () => {
        const helloLifecycle = document.querySelector("hello-lifecycle");
        if (helloLifecycle) leftPanel.removeChild(helloLifecycle);
      });

      /* 需要在服务器环境 */
      const moveBtn = document.getElementById("moveBtn");
      moveBtn.addEventListener("click", () => {
        const helloLifecycle = document.querySelector("hello-lifecycle");
        const iframe = document.getElementById("iframe");
        if (helloLifecycle && iframe) {
            iframe.contentWindow.document.body.appendChild(helloLifecycle);
        }
      });
    </script>
  </body>
</html>
